﻿namespace Windows32
{
    using System;
    using System.Drawing;
    using System.Runtime.InteropServices;

    public class DeviceContextBase : IDisposable
    {
        private int InitMode = 0;
        protected IntPtr intHDC = IntPtr.Zero;
        private IntPtr intHwnd = IntPtr.Zero;
        private Graphics myGraphics = null;

        [DllImport("gdi32.dll", CharSet=CharSet.Auto)]
        private static extern IntPtr CreateCompatibleDC(IntPtr hDC);
        [DllImport("gdi32.dll", CharSet=CharSet.Auto)]
        private static extern IntPtr CreateDC(string strDriver, string strDevice, int Output, int InitData);
        [DllImport("gdi32.dll", CharSet=CharSet.Auto)]
        private static extern bool DeleteDC(IntPtr hDC);
        public virtual void Dispose()
        {
            if (this.intHDC != IntPtr.Zero)
            {
                if (this.InitMode == 1)
                {
                    ReleaseDC(this.intHwnd, this.intHDC);
                }
                if (this.InitMode == 2)
                {
                    this.myGraphics.ReleaseHdc(this.intHDC);
                }
                if (this.InitMode == 3)
                {
                    DeleteDC(this.intHDC);
                }
                if (this.InitMode == 4)
                {
                    DeleteDC(this.intHDC);
                }
            }
            this.intHDC = IntPtr.Zero;
            this.intHwnd = IntPtr.Zero;
            this.InitMode = 0;
            this.myGraphics = null;
        }

        [DllImport("User32.dll", CharSet=CharSet.Auto)]
        private static extern IntPtr GetDC(IntPtr hWnd);
        protected void InitCompatibleDC(IntPtr hdc)
        {
            this.intHDC = CreateCompatibleDC(hdc);
            this.InitMode = 4;
        }

        protected void InitFromDriverName(string strDriver)
        {
            this.intHDC = CreateDC(strDriver, null, 0, 0);
            this.InitMode = 3;
        }

        protected void InitFromGraphics(Graphics g)
        {
            this.intHDC = g.GetHdc();
            this.myGraphics = g;
            this.InitMode = 2;
        }

        protected void InitFromHDC(IntPtr hdc)
        {
            this.intHDC = hdc;
            this.InitMode = 0;
        }

        protected void InitFromHWnd(IntPtr hwnd)
        {
            this.intHwnd = hwnd;
            this.intHDC = GetDC(hwnd);
            this.InitMode = 1;
        }

        [DllImport("User32.dll", CharSet=CharSet.Auto)]
        private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
        public IntPtr SelectObject(IntPtr obj)
        {
            return SelectObject(this.intHDC, obj);
        }

        [DllImport("gdi32.dll", CharSet=CharSet.Auto)]
        private static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);

        public IntPtr HDC
        {
            get
            {
                return this.intHDC;
            }
        }
    }
}

